package org.prothlisberger.perf;

import java.io.PrintWriter;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;

public class PerformanceSet {
	private int iterations = 10;
	private long addTime;
	private long iterTime;
	private long delTime;

	/**
	 * Set performace test Speed test of HashSet, LinkedHashSet and TreeSet
	 * Testing speed of: adding and removing objects from the set and iterating
	 * through the set
	 */

	public void execute(PrintWriter aWriter) {
		HashSet<Integer> hashSet = new HashSet<Integer>();
		LinkedHashSet<Integer> linkedHashSet = new LinkedHashSet<Integer>();
		TreeSet<Integer> treeSet = new TreeSet<Integer>();

		addTime = 0;
		iterTime = 0;
		delTime = 0;
		for (int i = 1; i < iterations; i++) {
			test(hashSet);
		}
		printReport(hashSet, aWriter);

		addTime = 0;
		iterTime = 0;
		delTime = 0;
		for (int i = 1; i < iterations; i++) {
			test(linkedHashSet);
		}
		printReport(linkedHashSet, aWriter);

		addTime = 0;
		iterTime = 0;
		delTime = 0;
		for (int i = 1; i < iterations; i++) {
			test(treeSet);
		}
		printReport(treeSet, aWriter);
	}

	private void test(Set<Integer> set) {
		int size = 1000000;
		// adding 1mil. objects to the set
		long startTime = new Date().getTime();
		for (int i = 0; i < size; i++) {
			set.add(i);
		}
		long endTime = new Date().getTime();
		addTime += endTime - startTime;

		// iterating through the set
		startTime = new Date().getTime();
		for (Integer i : set) {

		}
		endTime = new Date().getTime();
		iterTime += endTime - startTime;

		// removing random 100000 objects from the set
		startTime = new Date().getTime();
		for (int i = 0; i < 100000; i++) {
			set.remove((int) (Math.random() * (size - i)));
		}
		endTime = new Date().getTime();
		delTime += endTime - startTime;
		set.clear();
	}

	private void printReport(Set<Integer> list, PrintWriter aWriter) {
		aWriter.println(list.getClass().getSimpleName()
				+ " - adding elements average time: "
				+ Math.round(addTime / iterations) + " msec");
		aWriter.println(list.getClass().getSimpleName()
				+ " - iteration average time: "
				+ Math.round(iterTime / iterations) + " msec");
		aWriter.println(list.getClass().getSimpleName()
				+ " - deleting random elements average time: "
				+ Math.round(delTime / iterations) + " msec");
		aWriter.flush();
	}

}
